/**
 * Created by no1 on 2015/7/24.
 */
'use strict';
let DD = require('./daoLoader');
let F = require('../function');
var Base = require('./Base');
var util = require("util");
let shopDao = new DD.mongoDB.ShopDao();


function ShopDispatcher(data) {
  data = data || {}
  data.dao = data.dao || shopDao;
  data.esDao = data.esDao || {};
  data.redisDao = data.redisDao || {};
  data.modelName = data.modelName || 'shop';
  data.modelType = data.modelType || 'mongo';
  this.data = data
  Base.call(this, this.data);
};
util.inherits(ShopDispatcher, Base);

/**
 *@todo 添加
 *@param  {Object}  date  数据
 *@ret    {Object}
 */
ShopDispatcher.prototype.add = function*(fields) {
  // 测试数据,为了后面list接口的排序
  function random(low, high) {
    return Math.random() * (high - low) + low;
  }

  function randomInt(low, high) {
    return Math.floor(Math.random() * (high - low) + low);
  }

  let aShopJson = {};
  //爬虫收集添加
  if (fields.act == 1) {
    // 必选项
    aShopJson = {
      id: fields.id,
      name: fields.name,
      image: fields.image,
      shopKeeper: fields.shopKeeper,
      tel: fields.tel,
      shopKeeperEmail: fields.shopKeeperEmail,
      address: fields.address,
      status: (fields.status != null) ? fields.status : 1,
      categories: fields.categories || [],
      loc: fields.loc,
      district: fields.district,
      remarks: fields.remarks,
      content: fields.content,
      authentication: 0,
      source: 2
    };
    if (true) {
      //aShopJson.desc = fields.desc;
      aShopJson.openTime = fields.openTime;//工作开始时间
      aShopJson.closeTime = fields.closeTime;//工作结束时间
      aShopJson.eTotal = fields.eTotal; //总评价得分
      aShopJson.eAverage = fields.eAverage; //评价
      aShopJson.eCount = fields.eCount; //评价总数
      aShopJson.discount = fields.discount; //优惠
      aShopJson.reservation = fields.reservation; //预定
      aShopJson.otherInfo = fields.otherInfo || '';
      aShopJson.decorationGrade = fields.decorationGrade; //评价
      aShopJson.serviceGrade = fields.serviceGrade; //评价
      aShopJson.effectGrade = fields.effectGrade; //评价
    } else {
      aShopJson.desc = "营业时间 9:00~21:00(模拟数据)";
      aShopJson.openTime = fields.openTime;
      aShopJson.closeTime = fields.closeTime;
      aShopJson.eTotal = random(1, 100).toFixed(2); //总评价得分
      aShopJson.eAverage = random(1, 5).toFixed(2); //评价
      aShopJson.eCount = randomInt(1, 10); //评价总数
      aShopJson.discount = randomInt(1, 10); //优惠
      aShopJson.reservation = randomInt(1, 10); //预定
      aShopJson.otherInfo = fields.otherInfo || '';//
      aShopJson.decorationGrade = random(1, 5).toFixed(2); //评价
      aShopJson.serviceGrade = random(1, 5).toFixed(2); //评价
      aShopJson.effectGrade = random(1, 5).toFixed(2); //评价
    }
  }
  //美容日记添加
  else if (fields.act == 2) {
    if (!fields.name) return F.returnData(1, '必须添加名字');
    fields.lastCode || (fields.lastCode = 0);
    aShopJson = {
      name: fields.name,
      authentication: 0,
      source: 3,
      integrity: 0
    }
    let retDis = yield F.getDataFromDispatcher('district', 'jointDistrictByAtLastCode', fields.lastCode);
    if (retDis.error == 1) aShopJson.district = [];
    else aShopJson.district = retDis.data;
  }
  //后台添加
  else if (fields.act == 3) {
    let arr = ['vendorid', 'name', 'image', 'tel', 'address', 'shopKeeper', 'shopKeeperTel', 'shopKeeperEmail', 'openTime', 'closeTime'
      , 'loc', 'graphicDetails']
    // 必选项
    for (let one of arr) {
      if (!fields[one]) return F.returnData(1, '必须有' + one);
      aShopJson[one] = fields[one];
    }
    aShopJson.authentication = 1;
    aShopJson.source = 1;
    aShopJson.status = (fields.status != null) ? fields.status : 1;

    //根据code查询并拼接地理位置
    if (!!fields.disCodes) {
      let retdis = yield F.getDataFromDispatcher('districtDispatcher', 'findByDis', {code: {$in: fields.disCodes}});
      if (retdis.error == 1 || retdis.data.length <= 0) return F.returnData(1, '地区编码有误')
      aShopJson.district = retdis.data;
    }
  }
  let ret = yield this.dao.findAndSave({name: aShopJson.name}, aShopJson);
  if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
  return F.returnData(0, ret.msg, ret.data);
};

/**
 * todo 更新
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
ShopDispatcher.prototype.update = function*(fields) {
  if (!fields.id) return F.returnData(1, '必须有id');
  let arr = ['vendorid', 'image', 'shopKeeper', 'tel', 'shopKeeperTel', 'shopKeeperEmail', 'address', 'status', 'loc'
    , 'desc', 'eTotal', 'eAverage', 'eCount', 'discount', 'reservation', 'decorationGrade', 'serviceGrade'
    , 'effectGrade', 'content', 'authentication', 'graphicDetails', 'deleteDescription', 'submitTime', 'openTime', 'closeTime'];
  let parameters = {};
  for (let one of arr) if (fields[one] != null) parameters[one] = fields[one];

  if (!!fields.cateCodes) {
    if (fields.cateCodes.length == 0) parameters.categories = [];
    else {
      let retCate = yield F.getDataFromDispatcher('category', 'findByDis', {code: {$in: fields.cateCodes}});
      if (retCate.error == 1) return F.returnData(1, '没有类别');
      parameters.categories = retCate.data;
    }
  }
  if (!!fields.disCodes) {
    if (fields.disCodes.length == 0) parameters.district = [];
    else {
      let retDis = yield F.getDataFromDispatcher('district', 'findByDis', {code: {$in: fields.disCodes}});
      if (retDis.error == 1) return F.returnData(1, '没有类别');
      parameters.district = retDis.data;
    }
  }
  //更新数据
  let ret = yield this.dao.findAndUpdate({id: fields.id}, parameters, false);
  if (ret.error == 1) return F.returnData(1, ret.msg);

  let json = JSON.parse(JSON.stringify({data: ret.data}));
  let retData = F.dataFilter(json, ['_id', 'createdAt', 'updateAt', '__v', '__t']);

  return F.returnData(0, ret.msg, retData.data);
};

/**
 * @todo 删除
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
ShopDispatcher.prototype.delete = function*(fields) {
  //step1 : 参数检测
  if (!fields.id) return F.returnData(1, 'error');
  let ret = yield this.dao.deleteShop(fields.id);
  return F.returnData(0, 'ok', ret);
};

/**
 * @todo 获取列表
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
ShopDispatcher.prototype.list = function*(fields) {
  let defaultMaxDistance = 500000
    , defaultLimit = 20, defaultPage = 1
    , limit = fields.pageSize || defaultLimit
    , page = fields.page || defaultPage
    , isPaging = fields.isPaging || 0
    , isSort = {id: -1}
    , pageSize = limit
    , opt = {}, parameters = {}, retDataList, retData = {}, retCount = {}, arr = [], count

  //list搜索
  if (fields.act == 1) {
    var skip = (page - 1) * limit;
    // 如果有districtCode,则按区域进行查找
    var districtCode = fields.districtCode;
    if (typeof districtCode !== 'undefined') {
      var cateCodes = fields.cateCodes;
      var result = yield this.dao.findByDistrictAndCate(districtCode, cateCodes, limit, skip, fields.sort);
      return F.returnMsg(200, 'OK', 3, result);
    }
    // 如果不传递 radius，不做 radius筛选
    if (typeof fields.radius === 'undefined' || fields.radius === 0) fields.radius = -1;

    // 首先进行距离筛选判断
    if (fields.radius) {
      if (fields.radius > 0 && !fields.loc) return F.returnData(1, '指定半径,却没有经纬度', fields);
      if (fields.radius > defaultMaxDistance) fields.radius = defaultMaxDistance;
      var cord = fields.loc;
      var cateCodes = fields.cateCodes;
      var result = yield this.dao.findByDistanceAndCate(cord, fields.radius, cateCodes, limit, skip, fields.sort);
      return F.returnData(0, 'OK', result);
    }
    return F.returnData(1, '暂不支持', fields);
  }
  //根据ID集合搜索
  else if (fields.act == 2) {
    if (fields.ids.length == 0)return F.returnData(1, '必须有ids');
    let opt = {
      _id: 0,
      id: 1,
      name: 1,
      loc: 1,
      image: 1,
      address: 1,
      eAverage: 1,
      discount: 1,
      reservation: 1,
      district: 1
    };
    let ret = yield this.dao.getByQuery({id: {$in: fields.ids}}, opt, page, limit);

    if (ret.error == 1) return F.returnData(1, ret.msg);
    let json = JSON.parse(JSON.stringify({data: ret.data}));
    let retData = F.dataFilter(json, ['_id']);
    return F.returnData(0, ret.msg, retData.data);
  }
  //根据商家(前台)
  else if (fields.act == 3) {
    let opt = {}
      , arr = ['id', 'name', 'image', 'district', 'loc', 'address', 'eAverage', 'discount', 'reservation', 'decorationGrade', 'serviceGrade', 'effectGrade', 'dist']

    for (let one of arr) opt[one] = 1;
    let ret = yield this.dao.getByQuery({vendorid: fields.vendorid}, opt, page, pageSize);
    if (ret.error == 1) return F.returnData(1, ret.msg);
    let json = JSON.parse(JSON.stringify(ret.data));
    let retData = F.dataFilter(json, ['_id']);


    return F.returnData(0, ret.msg, retData);
  }
  //根据商店名称模糊查询
  else if (fields.act == 4) {
    let opt = {};
    opt._id = 0;
    let arr = ['id', 'name']
    fields.page || (fields.page = 1);
    fields.pageSize || (fields.pageSize = 50);
    for (let one of arr) opt[one] = 1;
    let str = fields.name.replace(/[\+]*[\*]*[\?]*[\$]*[\^]*[\\]*/g, '')
    str = str.split('').join('+[\\s\\S]*');
    //let str = fields.name + '*';
    let re = new RegExp(str, 'i');
    let ret = yield this.dao.getByQuery({name: {$regex: re}}, opt, fields.page, fields.pageSize);
    if (ret.error == 1) return F.returnData(1, ret.msg);
    return F.returnData(0, ret.msg, ret.data);
  }
  //根据地区编码查询(适用 后台项目编辑)
  else if (fields.act == 5) {
    if (!fields.districtCode) return F.returnData(1, '必须有地区编码');
    if (!fields.vendorid) return F.returnData(1, '必须有商家id');
    let arr = ['id', 'name', 'status'];
    for (let one of arr) opt[one] = 1;
    //拼接查询条件
    parameters.vendorid = fields.vendorid;
    parameters['district.code'] = fields.districtCode;
    if (fields.status != null) parameters.status = fields.status;

    //查询数据
    let ret = yield this.dao.getByQueryPor(parameters, opt, {page: page, pageSize: pageSize}, {id: -1});
    if (ret.error == 1) return F.returnData(1, ret.msg);
    retDataList = ret.data;

    let json = JSON.parse(JSON.stringify(retDataList));
    retDataList = F.dataFilter(json, ['_id']);
    //拼接数据
    if (isPaging == 1) {
      retCount = yield this.dao.getCountByQuery(parameters);
      if (retCount.error == 1) return F.returnData(1, retCount.msg);
      retData.list = retDataList;
      retData.count = retCount.data;
    } else retData = retDataList;
    return F.returnData(0, ret.msg, retData);
  }
  //后台商家详情中的机构管理的列表,根据vendorType返回对应的数据
  else if (fields.act == 6) {
    if (!fields.vendorType) return F.returnData(1, '必须有vendorType');
    if (fields.vendorType == 2 && !fields.vendorid) return F.returnData(1, '必须有vendorid');

    let parameters = {}, opt = {}, retData = {}, sid = [], retDataList
      , arrDel = ['id', 'name', 'address', 'district', 'tel', 'shopKeeper', 'status']
      , isPaging = fields.isPaging || 0;
    for (let one of arrDel) opt[one] = 1;


    //拼接请求数据
    if (!!fields.vendorid) parameters.vendorid = fields.vendorid;
    if (!!fields.status) parameters.status = fields.status;
    //获取商店列表
    let ret = yield this.dao.getByQueryPor(parameters, opt, {page: page, pageSize: pageSize}, {id: -1});
    if (ret.error == 1) return F.returnData(1, ret.msg);
    retDataList = ret.data;
    //获取总条数
    let retCount = yield this.dao.getCountByQuery(parameters);
    if (retCount.error == 1) return F.returnData(1, retCount.msg);
    //查询sellUser信息
    if (fields.vendorType == 2) {
      for (let one of retDataList) sid.push(one.id);
      let retSUList = yield F.getDataFromDispatcher('sellUserDispatcher', 'findByDis', {sid: {$in: sid}});
      let retDataListNew = [];
      for (let shop of retDataList) {
        for (let user of retSUList.data) {
          if (shop.id == user.sid) {
            shop.uid = user.uid;
            shop.sellUserid = user.id;
            shop.userName = user.name;
            break;
          }
        }
        retDataListNew.push(shop);
      }
      retDataList = retDataListNew;
    }
    //过滤数据
    let json = JSON.parse(JSON.stringify(retDataList));
    retDataList = F.dataFilter(json, ['_id']);
    //拼接数据
    if (isPaging == 1) {
      retData.list = retDataList;
      retData.count = retCount.data;
    } else retData = retDataList;
    return F.returnData(0, ret.msg, retData);
  }
  //总后台删除管理中的机构
  else if (fields.act == 8) {
    //拼接查询条件
    if (fields.name != null) {
      let str = fields.name.replace(/[\+]*[\*]*[\?]*[\$]*[\^]*[\\]*/g, '')
      str = str.split('').join('+[\\s\\S]*');
      //let str = fields.name + '*';
      let re = new RegExp(str, 'i');
      parameters.name = {$regex: re};
    }
    if (fields.submitTime != null) {
      let submitTime = fields.submitTime
      let start = new Date(submitTime);
      let end = F.addDays(start, 1);
      parameters.submitTime = {$gte: start, $lt: end};
      isSort = {submitTime: -1};
    }
    parameters.status = (fields.status == null) ? 2 : fields.status;
    //提取数据
    arr = ['id', 'name', 'vendorid', 'submitTime', 'status', 'deleteDescription'];
    for (let one of arr) opt[one] = 1;
    //查询项目版本
    let ret = yield this.dao.getByQueryPor(parameters, opt, {page: page, pageSize: pageSize}, isSort);
    if (ret.error == 1) return F.returnData(1, ret.msg);
    retDataList = ret.data;

    //查询项目对应的商家
    let vendorids = [];
    for (let one of retDataList) if (!!one.vendorid && vendorids.indexOf(one.vendorid) == -1) vendorids.push(one.vendorid);
    let retVendorList = yield F.getDataFromDispatcher('vendorDispatcher', 'findByDis', {id: {$in: vendorids}});
    if (retVendorList.error == 1) return F.returnData(1, retVendorList.msg);
    //拼接数据
    for (let one of retDataList) {
      for (let vendor of retVendorList.data) {
        if (one.vendorid == vendor.id) {
          one.vendorName = vendor.name;
          break;
        }
      }
    }


    //过滤数据
    let json = JSON.parse(JSON.stringify(retDataList));
    retDataList = F.dataFilter(json, ['_id']);
    //返回数据
    if (isPaging == 1) {
      retCount = yield this.dao.getCountByQuery(parameters);
      retData.list = retDataList;
      retData.count = retCount.data;
    } else retData = retDataList
    return F.returnData(0, 'ok', retData);
  }
};

/**
 *  todo 条件查询
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
ShopDispatcher.prototype.listByQut = function*(fields) {
  let queryObj = fields.queryObj
    , opt = {}
    , page = fields.page || 1
    , pageSize = fields.pageSize || 50
    , arrDel = ['_id', '__v', '__t', 'createdAt', 'updateAt', 'otherInfo'];

  for (let one of arrDel) opt[one] = 0;

  let ret = yield  this.dao.getByQuery(queryObj, opt, page, pageSize);
  if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
  return F.returnData(0, ret.msg, ret.data);
};

/**
 * @todo 获取详情
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
ShopDispatcher.prototype.detail = function*(fields) {
  //step1 : 参数检测
  if (!fields.id) return F.returnData(1, 'error');
  var ret = yield this.dao.getOneByQuery({id: fields.id});
  if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
  let json = JSON.parse(JSON.stringify({data: ret.data}));
  let retData = F.dataFilter(json, ['_id', '__v', '__t', 'createdAt', 'updateAt', 'otherInfo']);
  return F.returnData(0, 'ok', retData.data);
};

/**
 * @todo 获取商店的地理列表
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
ShopDispatcher.prototype.getDistrict = function*(fields) {
  if (!fields.vendorid) return F.returnData(1, '必须有商家id');
  let arrDel = ['id', 'name', 'address', 'district', 'tel', 'shopKeeper']
    , opt = {}
    , ret
    , levelA = []
  for (let one of arrDel) opt[one] = 1;
  ret = yield this.dao.getBydistinct('district.code', {vendorid: fields.vendorid, status: 1});
  if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
  let retdistrict = yield F.getDataFromDispatcher('districtDispatcher', 'findByDis', {code: {$in: ret.data}});
  if (retdistrict.error == 1) return F.returnData(1, retdistrict.msg, retdistrict.data);
  //拼接数据
  let districtList = retdistrict.data;
  for (let i in districtList) {
    if (districtList[i].pCode == 0) {
      levelA.push(districtList[i]);
      districtList.splice(i, 1);
    }
  }
  for (let one of levelA) {
    for (let dis of districtList) {
      if (one.code == dis.pCode) {
        one.nextDis || (one.nextDis = []);
        one.nextDis.push(dis);
        break;
      }
    }
  }
  return F.returnData(0, 'ok', levelA);
};

/**
 *@todo 根据门店的集合拼接商品的门店集合
 *@param  {Object}  paramShops  门店集合
 */
ShopDispatcher.prototype.jointShop = function*(paramShops) {
  let shops = [];//临时装载多个门店参数的数组
  for (let one of paramShops) {//遍历
    if (one.sid) {
      let shop = {};//临时装载门店参数
      let shopRet = yield this.dao.getOneByQuery({id: one.sid});//找到对应的门店
      if (shopRet.error == 1) return F.returnData(1, shopRet.msg);
      shop.sid = one.sid;
      shop.shopInfo = shopRet.data._id;
      shop.sName = shopRet.data.name;//商店名称
      shop.loc = shopRet.data.loc || [];//地理坐标
      shop.district = shopRet.data.district || [];//区域
      shop.sPrice = one.sPrice || 0;//该店商品售价
      shop.sAmount = one.sAmount || 0;//该店商品的库存
      //添加新的shop到shops
      shops.push(shop);
    }
    else return F.returnData(1, '必须有sid')

  }
  return shops;
};

/**
 * 根据机构id集合拼接
 * @param paramShops
 */
ShopDispatcher.prototype.jointShopByids = function*(ids, vendorid) {
  let arrDel = ['__v', '__t', 'createdAt', 'updateAt', 'otherInfo']
    , opt = {}
    , shops = [];
  for (let one of arrDel) opt[one] = 0;
  let ret = yield this.dao.getByQuery({id: {$in: ids}, status: 1, vendorid: vendorid}, opt);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  for (let one of ret.data) {
    let shop = {};
    shop.shopInfo = one._id;
    shop.sid = one.id;
    shop.sName = one.name;//商店名称
    shop.loc = one.loc || [];//地理坐标
    shop.district = one.district || [];//区域
    //添加新的shop到shops
    shops.push(shop);
  }
  return F.returnData(0, 'ok', shops);
};

/**
 * 内部调用
 * @param Que
 * @returns {{error, msg, data}|{error, msg}}
 */
ShopDispatcher.prototype.findByDis = function*(Que) {
  let arrDel = ['_id', '__v', '__t', 'createdAt', 'updateAt', 'status']
    , opt = {};
  for (let one of arrDel) opt[one] = 0;
  let ret = yield this.dao.getByQuery(Que, opt);
  if (ret.error == 1) F.returnData(1, ret.msg, ret.data);
  return F.returnData(0, ret.msg, ret.data);
};

//ShopDispatcher.prototype.findCountListByDis = function*(QueList) {
//  let retArr = [];
//  for (let one of QueList) {
//    let ret = this.dao.getCountByQuery(one);
//    retArr.push(ret.data);
//  }
//  return retArr
//}
module.exports = ShopDispatcher;